Refine SwiftUI migration shell#225
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: e7c6352cdb
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| } | ||
|
|
||
| static var readinessURL: URL { | ||
| baseURL.appendingPathComponent("api/health/ready") |
There was a problem hiding this comment.
Use a readiness endpoint the server serves
The macOS shell polls /api/health/ready, but the Node runtime in this commit only registers /api/app-identity and there is no api/health/ready route in server.js. When the packaged app launches an otherwise healthy runtime, waitForRuntime will receive 404s for the full timeout, leave the menu in Starting/timeout, and skip the automatic browser open.
Useful? React with 👍 / 👎.
| if let persistedWorkDir = environment["NMAPUI_RUNTIME_WORKDIR"], !persistedWorkDir.isEmpty { | ||
| runtimeWorkDir = URL(fileURLWithPath: persistedWorkDir) | ||
| } else { | ||
| runtimeWorkDir = URL(fileURLWithPath: FileManager.default.currentDirectoryPath) |
There was a problem hiding this comment.
Set a valid runtime workdir for bundled launches
When the app is opened from bundle.sh/install.sh via LaunchServices without NMAPUI_RUNTIME_WORKDIR, this falls back to the app process's current directory while the default command is node server.js, and the bundle does not copy server.js into that directory. In the normal installed-app path the runtime can start from / or another LaunchServices cwd and node cannot find server.js, so the menu bar app cannot launch the backend until the user manually configures a workdir.
Useful? React with 👍 / 👎.
| function runGoogleDriveHelper(args, dataDir, input = null) { | ||
| return new Promise((resolve) => { | ||
| const helperCommand = process.env.NMAPUI_GOOGLE_DRIVE_HELPER | ||
| || path.join(__dirname, 'packaging/macos/.build/out/Products/Debug/GoogleDriveHelper'); |
There was a problem hiding this comment.
Point the bridge at the built helper
build.sh and bundle.sh invoke plain swift build, whose product is under the SwiftPM build directory such as packaging/macos/.build/debug/GoogleDriveHelper, but the default here points at .build/out/Products/Debug and no script creates that path. With the default environment, every Google Drive status/connect/upload call spawns a nonexistent binary, and because there is no child error handler the runtime crashes instead of reporting helper failure.
Useful? React with 👍 / 👎.
| exit(0) | ||
|
|
||
| case "save-credentials": | ||
| let payloadData = credentialsJSON.isEmpty ? Data("{}".utf8) : Data(credentialsJSON.utf8) |
There was a problem hiding this comment.
Read credentials from stdin on save
save_google_drive_credentials in server.js still passes the uploaded file contents as stdin via runGoogleDriveHelper(['save-credentials'], DATA_DIR, data.credentialsJson || ''), but this branch only reads the --credentials-json argument and substitutes {} when it is absent. Through the Settings UI, importing any credentials file therefore overwrites .google_drive/credentials.json with {}, and the subsequent auth flow always reports missing OAuth credentials.
Useful? React with 👍 / 👎.
| let filePaths = args | ||
| .filter { $0.hasPrefix("/") } | ||
| .map { URL(fileURLWithPath: $0) } |
There was a problem hiding this comment.
Parse only files passed after --files
The bridge appends --root <DATA_DIR> to every helper invocation, and the server calls upload with --files ...existingFiles; filtering all absolute arguments here also captures the data directory from --root while ignoring the --files boundary. In a real report upload the helper tries Data(contentsOf:) on the data directory after the report files, causing Google Drive sync to fail even when credentials are valid.
Useful? React with 👍 / 👎.
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: a4c709b2b9
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| var configured: Bool? | ||
| var connected: Bool? | ||
| var expiresAt: String? | ||
| var authURL: String? |
There was a problem hiding this comment.
Return the auth URL under the expected key
HelperResponse is encoded with Swift property names, so the successful auth-url response contains authURL, while the existing settings handler checks data.auth_url before opening the browser. With valid credentials, clicking Connect receives success: true but no auth_url, causing the UI to show the authorization error and never open Google OAuth.
Useful? React with 👍 / 👎.
| let credentials = readJSON([String: String].self, from: paths.credentials) ?? [:] | ||
| guard let clientId = credentials["client_id"], !clientId.isEmpty, | ||
| let _ = credentials["client_secret"], !redirectURI.isEmpty else { |
There was a problem hiding this comment.
Accept Google Cloud's nested credentials JSON
This decodes credentials as a flat [String: String] and then requires top-level client_id/client_secret. The previous helper unwrapped the standard Google Cloud Console shapes under installed or web; after importing that normal credentials file, status/auth-url treat it as missing credentials and the Drive connection flow cannot start.
Useful? React with 👍 / 👎.
| @@ -0,0 +1,43 @@ | |||
| #!/usr/bin/env node | |||
| const { io } = require('socket.io-client'); | |||
There was a problem hiding this comment.
Add the Socket.IO client dependency for the smoke test
The new smoke helper requires socket.io-client, but package.json/package-lock.json only install the server package socket.io. In a clean checkout or the GitHub Actions job after npm install, npm run nightly-eval:run reaches this script and Node exits with MODULE_NOT_FOUND, so the nightly evaluation fails after the startup probes instead of recording a pass.
Useful? React with 👍 / 👎.
|
|
||
| <key>ProgramArguments</key> | ||
| <array> | ||
| <string>/Users/seandolbec/Projects/NmapUI/scripts/nightly_product_eval.sh</string> |
There was a problem hiding this comment.
Generate the LaunchAgent paths from the checkout
nightly-eval:launchd-install copies this plist unchanged, so on any machine where the repo is not at /Users/seandolbec/Projects/NmapUI, launchd tries to execute a nonexistent script and uses nonexistent working/log paths. Installing from the repo's npm script therefore creates a scheduler that never runs for other checkouts unless users manually edit the plist.
Useful? React with 👍 / 👎.
💡 Codex ReviewTM-NmapUI/packaging/macos/Sources/GoogleDriveHelper/main.swift Lines 231 to 232 in 3969fc6 When a connected account has both an On every successful upload this discards the Line 1129 in 3969fc6 After copying the scan XML into the report archive, the XSLT step now reads the reusable work-file path again after asynchronous gowitness capture. If another scan starts while screenshot/report generation is still pending, ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
Keep the SwiftUI app unprivileged and elevate only nmap via a LaunchDaemon helper, host the perfected HTML UI full-bleed, generate HTML/PDF reports after complete scans, and expose helper install/status in Settings for unattended daily/weekly runs.
After complete scans, upload HTML/PDF/XML when Drive sync is enabled and connected, enrich auto-scan config with next-run metadata for the dashboard countdown banner, and fix a few contract tests.
Detect the primary interface more reliably, keep targets sorting stable, and split the phase-two scan, HTML transform, and cleanup steps for clearer failures.
Connect/disconnect now use the native helper with a local OAuth callback server, credentials import is normalized for Google console JSON, settings persist save-to-desktop, and completed reports can copy to Desktop/NmapUI Reports.
💡 Codex ReviewWhen the privileged helper is installed, a On multi-user Macs, setting the root helper socket to TM-NmapUI/scripts/nightly_product_eval.sh Line 198 in 13931ed The nightly job now starts For unattended auto-scans, report generation always builds the customer profile with the hard-coded ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
This PR is the clean, conflict-free replay of the SwiftUI/native shell migration slice on top of current main.\n\nScope:\n- SwiftUI macOS app shell and menu bar launcher\n- Native Google Drive helper bridge\n- Launcher/startup cleanup for the fixed loopback runtime\n- Nightly eval path updates and smoke probes\n- Packaging sources for the macOS app bundle\n\nValidation:\n- ./packaging/macos/bundle.sh\n- ./scripts/nightly_product_eval.sh --run\n\nBranch: codex/swiftui-migration-clean